﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Forms;


namespace NFox.Pycad.Core
{
    public class Application : PluginBase
    {

        #region Cmds

        internal static Dictionary<string, string> CuixFlies;
        internal static Dictionary<string, dynamic> InitCommands;
        internal static Dictionary<string, dynamic> InitLispFunctions;
        internal static Dictionary<string, dynamic> Commands;
        internal static Dictionary<string, dynamic> LispFunctions;
        internal static bool Initialized;
        internal static bool LoadFirst = true;

        #endregion

        #region Plugin
        public override void Initialize()
        {
            SetVariable("acPath", new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory));
            AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
            base.Initialize();
            Engine = new Engine();
            //加载模块
            Engine.GetProjects();
            Start();
        }

        static Assembly _ass = Assembly.GetExecutingAssembly();
        static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            if (args.Name == _ass.FullName)
                return _ass;
            //string name = args.Name.ToLower();
            //if (name.EndsWith(".dll"))
            //    name = name.Substring(0, name.Length - 4);

            //Assembly[] assembies = AppDomain.CurrentDomain.GetAssemblies();
            //foreach (var ass in assembies)
            //{
            //    var assname = ass.GetName();
            //    if (assname.FullName == args.Name || ass.GetName().Name.ToLower() == name)
            //        return ass;
            //}
            return null;
        }

        protected override void OnLoading()
        {
            try
            {

                DynamicCompiler.AddSystemCommand("pyrb", new Action(Start));
                DynamicCompiler.AddSystemCommand("pyload", () => Engine.Setup());

                Engine.AddSysProject(Engine.SupportPath.GetDirectory("pycad"));
                Values = new Dictionary<string, dynamic>();

                //初始化引擎
                Engine.Restart();
                Engine.AddSearchPath(GetVariable("acPath").FullName);
                Engine.LoadAssembly(Assembly.GetExecutingAssembly());

                //从acad.py中获取初始化信息
                Engine.TryReference("pycad.dll");
                Engine.Execute("from pycad.acad import *");
                SetVariable("acApp", Engine.Execute("acap.Application"));

            }
            catch (Exception ex)
            {
                MessageBox.Show("Err:" + ex.Message);
            }

        }


        protected async override void OnLoaded()
        {
            try
            {

                //获取当前版本Cad的Mgd程序集
                List<string> mgds = new List<string>();
                var mainmgds = Engine.Execute("pycad").system.mgds[0];
                foreach (string name in mainmgds)
                {
                    string fullname = GetVariable("acPath").FullName + "\\" + name;
                    if (fullname != null)
                        mgds.Add(fullname);
                }
                DynamicCompiler.Mgdlls = mgds;

                if (LoadFirst)
                {
                    //首次加载动态编译pye命令集
                    DynamicCompiler.BuildSystemAssembly();
                    LoadFirst = false;
                }

                //运行init函数处理界面相关 
                Initialized = true;
                InitCommands = new Dictionary<string, dynamic>();
                InitLispFunctions = new Dictionary<string, dynamic>();
                CuixFlies = new Dictionary<string, string>();
                Engine.LoadProjects();
                DynamicCompiler.BuildUserAssembly(InitCommands, InitLispFunctions);

                var menus = GetVariable("acApp").MenuGroups;
                foreach (var cuix in CuixFlies)
                {
                    try { menus.Item(cuix.Key); }
                    catch
                    {
                        try { menus.Load(cuix.Value); }
                        catch { }
                    }
                }

                await Task.Run(() =>
                {
                    //加载模块并利用装饰器获取函数信息
                    //动态编译用户命令集
                    Initialized = false;

                    if (Commands != null)
                        DynamicCompiler.ClearCommands(Commands);
                    Commands = new Dictionary<string, dynamic>();
                    LispFunctions = new Dictionary<string, dynamic>();
                    Engine.RegistCommands();
                    DynamicCompiler.AddCommands(Commands);
                });

            }
            catch (Exception ex)
            {
                MessageBox.Show("Err:" + ex.Message);
            }

        }

        #endregion

    }

}
